/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include <面/面.h>
#include <物体/物体.h>
#include <材质/预设材质.h>

#include "节点数据声明.h"
#include "当前默认操作数据.h"



#define _DEF_变换插座创建_ DEF_创建Vec3插座_v1_I(L"位置"); DEF_创建Vec3插座_v1_I(L"旋转"); DEF_创建Vec3插座_v1_I(L"缩放");
#define _DEF_变换属性创建_                                                                                         \
	if (m_Ob == nullptr) {                                                                                         \
		m_Ob = f_node_网格节点创建物体数据(m_Ctx);                                                                 \
		f_get输出插座(1)->f_setData(m_Ob);                                                                         \
		f_NodeCtx_录物体类节点(this);                                                                              \
	}                                                                                                              \
	m_位置 = f_alloc_Vec3Prop(&m_Ob->m_变换.location, L"位置");                                                    \
	m_旋转 = f_alloc_Vec3Prop(&m_Ob->m_变换.rotation, L"旋转");                                                    \
	m_缩放 = f_alloc_Vec3Prop(&m_Ob->m_变换.scale, L"缩放");                                                       \
	m_位置.m_私有 = true;                                                                                          \
	m_旋转.m_私有 = true;                                                                                          \
	m_缩放.m_私有 = true;                                                                                          \






typedef struct {
	S_单色材质* m_描边;
	S_单色材质* m_面;
	S_单色材质* m_线;
}S_单色材质包;

enum E_虚拟体类型 : uint8 {
	E_交叉轴,
	E_方向轴,
	E_线框球,
};

struct S_虚拟体ID偏移 {
	static S_VkDrawIndexedIndirectCommand Indirect_交叉轴;
	static S_VkDrawIndexedIndirectCommand Indirect_方向轴;
	static S_VkDrawIndexedIndirectCommand Indirect_线框球;
};


S_物体* f_node_初始化单虚拟体网格(S_设备环境& ctx);
void f_node_释放虚拟体网格();


void f_改变网格容器大小(std::vector<S_Mesh*>& meshs, uint32 num, S_设备环境& ctx, E_网格数据枚举 type);

void f_node_网格绘制属性设置(S_物体* ob);
void f_node_创建网格物体数据(S_物体* ob, S_设备环境& ctx);

S_物体* f_node_网格节点创建物体数据(S_设备环境& ctx);
S_物体* f_node_网格节点创建连续线物体数据(S_设备环境& ctx);
S_物体* f_node_网格节点创建线段物体数据(S_设备环境& ctx);
S_物体* f_node_网格节点创建点物体数据(S_设备环境& ctx);
//S_物体* f_node_创建多边形物体数据(S_设备环境& ctx);
//void	f_node_物体节点创建物体数据(S_物体* ob);
void    f_node_构建多边形网格对象(S_设备环境& ctx, S_物体* ob);

void f_创建网格物体组(std::vector<S_物体*>& 物体, uint32 num, S_设备环境& ctx);
void f_node_创建模型物体组(S_OBArray* 物体, uint32 num, E_物体类型 type, S_设备环境& ctx);
void f_销毁物体组(std::vector<S_物体*>& 物体);
void f_node_销毁模型网格(S_物体* ob);

void f_node_创建纹理组(S_TexArray* 纹理, uint32 num, S_设备环境& ctx);
void f_node_销毁纹理组(S_TexArray* 纹理);



void	f_node_物体节点创建物体数据_单色明暗(S_物体* ob);
void	f_node_将现有物体包装成骨骼网格(S_设备环境& ctx, S_物体* 骨骼, S_物体* 骨节);

S_物体* f_node_线网格节点创建物体数据(S_设备环境& ctx);
S_物体* f_node_创建虚拟体(S_设备环境& ctx, E_虚拟体类型 类型);
S_物体* f_node_创建虚线(S_设备环境& ctx);
S_物体* f_node_创建骨架物体(S_设备环境& ctx);
S_物体* f_node_创建骨头物体(S_设备环境& ctx);
S_物体* f_node_创建包围盒虚拟体(S_设备环境& ctx);
//S_物体* f_node_创建点光源虚拟网格(S_设备环境& ctx);
//S_物体* f_node_创建平行光虚拟网格(S_设备环境& ctx);
S_物体* f_node_创建虚拟体网格物体(S_设备环境& ctx, E_物体类型 类型);
S_物体* f_node_创建虚拟体(S_设备环境& ctx);
void    f_node_创建平行光虚拟体(S_物体* ob);
void    f_node_创建点光源虚拟体(S_物体* ob);
void    f_node_创建聚光灯虚拟体(S_物体* ob);
void    f_node_创建区域光虚拟体(S_物体* ob);


void    f_node_移除虚拟体(S_物体* ob);
void    f_node_设置灯光虚拟网格类型(S_物体* ob, E_物体类型 类型);
void	f_node_设置灯光虚拟网格范围(S_物体* ob, const vec2& r);
void    f_node_设置点光源虚拟体绘制(S_VkDrawIndirectCommand& 中心圆间接, S_VkDrawIndirectCommand& 边界线间接, S_VkDrawIndirectCommand& 方向线间接, uint32 offset);
void    f_node_设置聚光灯虚拟体绘制(S_VkDrawIndirectCommand& 中心圆间接, S_VkDrawIndirectCommand& 边界线间接, S_VkDrawIndirectCommand& 方向线间接, uint32 offset);
void    f_node_设置方形区域光虚拟体绘制(S_VkDrawIndirectCommand& 中心圆间接, S_VkDrawIndirectCommand& 边界线间接, S_VkDrawIndirectCommand& 方向线间接, uint32 offset);
void    f_node_设置圆形区域光虚拟体绘制(S_VkDrawIndirectCommand& 中心圆间接, S_VkDrawIndirectCommand& 边界线间接, S_VkDrawIndirectCommand& 方向线间接, uint32 offset);
void    f_node_设置摄像机虚拟体绘制(S_VkDrawIndirectCommand& 中心圆间接, S_VkDrawIndirectCommand& 边界线间接, S_VkDrawIndirectCommand& 方向线间接, uint32 offset);

//S_物体* f_node_创建摄像机虚拟体(S_设备环境& ctx);
S_物体* f_node_创建摄像机虚拟体(S_物体* ob);
void    f_node_设置摄像机虚拟网格(S_物体* ob, S_摄像机* 摄像机);

void    f_node_创建立方体虚拟体(S_物体* ob);
void    f_node_设置立方体虚拟体绘制(S_VkDrawIndirectCommand& 中心圆间接, S_VkDrawIndirectCommand& 边界线间接, S_VkDrawIndirectCommand& 方向线间接, uint32 offset);
void    f_node_设置立方体虚拟网格(S_物体* ob, const vec3& size);
void    f_node_设置球体虚拟网格(S_物体* ob, const vec3& size);
void    f_node_设置链接线方体虚拟网格(S_物体* ob, const vec3& size, const vec3& loc);



//S_物体* f_node_创建虚拟体网格物体(S_设备环境& ctx, E_物体类型 类型);
S_物体* f_node_get多元素虚拟体根物体(S_设备环境& ctx);
S_物体* f_node_get单元素虚拟体根物体(S_设备环境* ctx);


S_物体* f_node_创建UV辅助操作虚拟体(S_设备环境& ctx);
void    f_node_设置UV操作虚拟体类型(S_物体* ob, uint32 type);
S_物体* f_node_创建单元素虚拟体(S_设备环境& ctx);
void    f_node_设置单元素虚拟体类型(S_物体* ob, uint32 type);

S_物体* f_node_创建圆柱UV辅助操作虚拟体(S_设备环境& ctx);

//S_物体* f_node_创建摄像机虚拟网格(S_设备环境& ctx, E_物体类型 类型);
//void    f_node_设置虚拟体绘制类型(S_物体* ob, uint32 type);


Inline void f_node_物体添加到主场景(S_物体* ob) {
	f_NodeCtx_get默认场景()->f_add物体({ ob }, E_场景物体容器类型::e_集合);
	S_节点数据::m_全局物体set.insert(ob);
}

Inline void f_node_从主场景移除物体(S_物体* ob) {
	f_NodeCtx_get默认场景()->f_remove物体(ob, E_场景物体容器类型::e_集合);
	S_节点数据::m_全局物体set.erase(ob);
}


Inline void f_node_物体添加到主场景(std::vector<S_物体*>& obs) {
	f_NodeCtx_get默认场景()->f_add物体(obs, E_场景物体容器类型::e_集合);
	S_节点数据::m_全局物体set.insert(obs.begin(), obs.end());
}

Inline void f_node_从主场景移除物体(std::vector<S_物体*>& obs) {
	f_NodeCtx_get默认场景()->f_remove物体(obs, E_场景物体容器类型::e_集合);
	for(auto& e : obs) S_节点数据::m_全局物体set.erase(e);
}


Inline void f_node_物体添加到主场景(S_OBArray* obs) {
	for (uint32 i = 0; i < obs->count; ++i) {
		f_node_物体添加到主场景(obs->ptr_userData[i]);
	}
}

Inline void f_node_从主场景移除物体(S_OBArray* obs) {
	for (uint32 i = 0; i < obs->count; ++i) {
		f_node_从主场景移除物体(obs->ptr_userData[i]);
	}
}

void    f_node_物体加入全局容器中(S_物体* ob);
void    f_node_物体从全局容器移除(S_物体* ob);
S_物体* f_node_从全局物体容器查找物体(std::wstring name);


S_单色材质包	f_node_get骨骼可视材质(S_设备环境& ctx);
void			f_node_回收骨骼可视材质(S_单色材质包 包);


S_材质*			f_node_getVecSphere材质(S_设备环境& ctx);
void			f_node_回收VecSphere可视材质(S_材质* 材质);




S_骨骼插座数据* f_node_创建编辑骨骼();

void f_node_创建物体(S_OBArray* obs);
void f_node_删除物体(S_OBArray* obs);
void f_node_删除物体(std::vector<S_物体*>& obs);
bool f_node_销毁物体();








